from PyQt5.QtWidgets import QMainWindow, QCheckBox, QLineEdit, QPushButton, QApplication, QInputDialog, QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QFileDialog, QMessageBox, QAction, QListView, QLabel
from PyQt5.QtGui import QIcon, QStandardItem, QStandardItemModel
from PyQt5.QtCore import pyqtSignal, QTimer, Qt

from ui.main import Ui_MainWindow
from ui import images

import os
import sys
import json
import threading
import time
import datetime
# import subprocess
# import configparser

from common.libs.logger import logger

import paho.mqtt.client as mqtt


class SubItem(QWidget):

    def __init__(self, parent=None, index=0, name='名称', topic='topic', payload='payload', send_time=1000, send_enable=False):
        super(SubItem, self).__init__(parent)
        self.layout = QHBoxLayout()
        self.layout.addWidget(QLabel('订阅主题:' + topic))
        self.setLayout(self.layout)


class SubListView(QListView):
    items = []

    def __init__(self, parent=None):
        super(SubListView, self).__init__(parent)
        # 模型
        self._model = QStandardItemModel(self)
        self.setModel(self._model)

    def addItem(self, topic=''):
        item = QStandardItem()
        self._model.appendRow(item)  # 添加item

        # 得到索引
        index = self._model.indexFromItem(item)
        widget = SubItem(topic=topic)
        item.setSizeHint(widget.sizeHint())  # 主要是调整item的高度

        # 设置自定义的widget
        self.setIndexWidget(index, widget)
        self.items.append(widget)

    def clearItem(self):
        self._model.clear()
        self.items = []


class PubItem(QWidget):
    signal_pub = pyqtSignal(str, str)

    def __init__(self, parent=None, info=None):
        super(PubItem, self).__init__(parent)
        self.layout = QHBoxLayout()
        # index = info['index']
        name = info['name']
        topic = info['topic'] 
        payload = info['payload'] 
        send_time = info['send_time'] 

        self.label_name = QLabel(name)
        self.lineEdit_topic = QLineEdit(topic)
        self.lineEdit_payload = QLineEdit(payload)
        self.lineEdit_send_time = QLineEdit(str(send_time))
        self.pushButton_send = QPushButton('发送')
        self.pushButton_send.clicked.connect(self.send)
        self.checkBox_send_enable = QCheckBox('定时')
        self.checkBox_send_enable.setCheckState(False)
        self.checkBox_send_enable.stateChanged.connect(self.sendStateChanged)
        self.pushButton_delete = QPushButton('删除')
        # self.layout.addWidget(QLabel(str(index)))

        self.layout.addWidget(self.label_name)
        self.layout.addWidget(self.pushButton_send)
        self.layout.addWidget(self.checkBox_send_enable)
        self.layout.addWidget(QLabel('主题:'))
        self.layout.addWidget(self.lineEdit_topic)
        self.layout.addWidget(QLabel('内容:'))
        self.layout.addWidget(self.lineEdit_payload)
        self.layout.addWidget(QLabel('定时:'))
        self.layout.addWidget(self.lineEdit_send_time)
        self.layout.addWidget(QLabel('ms'))
        self.layout.addWidget(self.pushButton_delete)
        self.setLayout(self.layout)

        self.timer_send = QTimer()
        self.timer_send.timeout.connect(self.send)
    
    def send(self):
        self.signal_pub.emit(self.lineEdit_topic.text(), self.lineEdit_payload.text())

    def sendStateChanged(self, state):
        if state > 0:
            self.timer_send.start(int(self.lineEdit_send_time.text()))
        else:
            self.timer_send.stop()
    

class PubListView(QListView):
    items = []
    info_items = []

    def __init__(self, parent=None):
        super(PubListView, self).__init__(parent)
        # 模型
        self._model = QStandardItemModel(self)
        self.setModel(self._model)

    def addItem(self, info):
        item = QStandardItem()
        self._model.appendRow(item)  # 添加item

        # 得到索引
        index = self._model.indexFromItem(item)
        widget = PubItem(info=info)
        widget.pushButton_delete.clicked.connect(self.deleteItem) 
        item.setSizeHint(widget.sizeHint())  # 主要是调整item的高度

        # 设置自定义的widget
        self.setIndexWidget(index, widget)
        self.items.append(widget)
        self.info_items.append(info)

    def deleteItem(self):
        for index in range(0, len(self.items)):
            widget = self.items[index]
            if widget.pushButton_delete == self.sender():
                self.info_items.pop(index)
                self.items.pop(index)
                self._model.removeRow(index)
                break

    def clearItem(self):
        self._model.clear()
        self.items = []


class MainWindow(QMainWindow, Ui_MainWindow):

    local_path = ''
    signal_txt = pyqtSignal(str)
    client = None
    sub_items = []

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.setWindowIcon(QIcon(':icons/images_rc/app.png'))
        self.setWindowTitle("辐射场mqtt调试助手")

        logger.info("start...")

        self.pushButton_mqtt_connect.clicked.connect(self.mqtt_connect)
        self.pushButton_sub.clicked.connect(self.mqtt_sub)
        self.pushButton_add_cmd.clicked.connect(self.add_pub)
        self.pushButton_clear_rx.clicked.connect(self.textBrowser_rx.clear)
        self.pushButton_clear_tx.clicked.connect(self.textBrowser_tx.clear)
        self.pushButton_save.clicked.connect(self.saveSubListJson)

        self.subListView = SubListView()
        self.pubListView = PubListView()
        self.verticalLayout_list_tx.addWidget(self.pubListView)
        self.verticalLayout_list_rx.addWidget(self.subListView)

        self.getSubListJson()

    def mqtt_connect(self):
        if self.pushButton_mqtt_connect.text() == '断开':
            self.pushButton_mqtt_connect.setText('连接')
            self.client.loop_stop()
            return

        def mqtt_on_connect(client, userdata, flags, rc):
            self.textBrowser_tx.append("Connected with result code: " + str(rc))
            self.pushButton_mqtt_connect.setText('断开')

        def mqtt_on_disconnect(client, userdata, rc):
            self.textBrowser_tx.append("Disconnect result code: " + str(rc))
            self.mqtt_thread_run = False

        def mqtt_on_message(client, userdata, msg):
            # self.textBrowser_rx.append(msg.topic + " " + str(msg.payload))
            self.textBrowser_rx.append("[%s] recv: topic->[%s], payload->[%s]" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msg.topic, (str(msg.payload))))
            self.textBrowser_rx.moveCursor(self.textBrowser_rx.textCursor().End)

        host = self.lineEdit_mqtt_host.text()
        port = int(self.lineEdit_mqtt_port.text())
        self.client = mqtt.Client()
        self.client.on_connect = mqtt_on_connect
        self.client.on_message = mqtt_on_message
        self.client.on_disconnect = mqtt_on_disconnect

        self.client.connect(host, port, 600)
        self.client.loop_start()

    def mqtt_send(self, topic, payload):
        if self.client is None:
            self.textBrowser_tx.append('请连接mqtt服务器!')
            return
        if self.client.is_connected is False:
            self.textBrowser_tx.append('请连接mqtt服务器!')
            return
        if topic == '':
            self.textBrowser_tx.append('topic 不能为空!')
            return
        self.client.publish(topic, payload=payload)
        self.textBrowser_tx.append('[%s] send: topic->[%s], payload->[%s]' % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), topic, payload))
        self.textBrowser_tx.moveCursor(self.textBrowser_rx.textCursor().End)

    def mqtt_sub(self):
        if self.client is None:
            self.textBrowser_rx.append('请连接mqtt服务器!')
            return
        if self.client.is_connected is False:
            self.textBrowser_rx.append('请连接mqtt服务器!')
            return
        topic = self.lineEdit_sub_topic.text()
        if topic == '':
            self.textBrowser_rx.append('topic 不能为空!')
            return
        self.client.subscribe(topic)
        self.subListView.addItem(topic=topic)

    def add_pub(self):
        name, ok = QInputDialog.getText(self, '名称', '名称：', QLineEdit.Normal, '')
        info = {
            "name": name,
            "topic": "xxx",
            "payload": "xxx",
            "send_time": 1000
        }
        self.pubListView.addItem(info)
        
        for i in range(0, len(self.pubListView.items)):
            item = self.pubListView.items[i]
            item.signal_pub.connect(self.mqtt_send)

    def saveSubListJson(self):
        items = []
        for item in self.pubListView.items:
            items.append({
                    "name": item.label_name.text(),
                    "topic": item.lineEdit_topic.text(),
                    "payload": item.lineEdit_payload.text(),
                    "send_time": item.lineEdit_send_time.text()
                })

        try:
            with open('%s/conf/subscribe_list.json' % os.getcwd(), 'w', encoding='utf8') as fp:
                json.dump(items, fp)
                QMessageBox.information(self, "提示", "保存成功")
        except Exception as e:
            logger.error(e)

    def getSubListJson(self):
        try:
            with open('%s/conf/subscribe_list.json' % os.getcwd(), 'r', encoding='utf8') as fp:
                obj = json.load(fp)
                for item in obj:
                    self.pubListView.addItem(item)
                for item in self.pubListView.items:
                    item.signal_pub.connect(self.mqtt_send)
        except Exception as e:
            logger.error(e)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    app.exec_()
